"""工具类或函数"""

import random
import re
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

import aiosmtplib

# Local
from config import MAIL_PARAMS

email_regex = r'^[a-z0-9]+[\._]?[a-z0-9]+@\w+\.\w{2,3}$'  # xxx.xxx@xx.com  xxx_xx@xxx.cn
pattern = re.compile(email_regex)


def validate_email(email):
    return pattern.match(email)


def generate_random_string(length=32, allowed_chars=(
        'abcdefghijklmnopqrstuvwxyz'
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
)):
    return ''.join(random.choice(allowed_chars) for i in range(length))


# https://stackoverflow.com/questions/60224850/send-mail-python-asyncio
async def send_mail_async(sender, to, subject, text, text_type='plain', **params):
    """Send an outgoing email with the given parameters.

    :param sender: From whom the email is being sent
    :type sender: str

    :param to: A list of recipient email addresses.
    :type to: list

    :param subject: The subject of the email.
    :type subject: str

    :param text: The text of the email.
    :type text: str

    :param text_type: Mime subtype of text, defaults to 'plain' (can be 'html').
    :type text: str

    :param params: An optional set of parameters. (See below)
    :type params; dict

    Optional Parameters:
    :cc: A list of Cc email addresses.
    :bcc: A list of Bcc email addresses.
    """

    # Default Parameters
    cc = params.get("cc", [])
    bcc = params.get("bcc", [])
    mail_params = params.get("mail_params", MAIL_PARAMS)

    # Prepare Message
    msg = MIMEMultipart()
    # msg.preamble = subject  # 不需要序言，当subject含有中文时会出现编码错误
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = ', '.join(to)
    if len(cc):
        msg['Cc'] = ', '.join(cc)
    if len(bcc):
        msg['Bcc'] = ', '.join(bcc)

    msg.attach(MIMEText(text, text_type, 'utf-8'))

    # Contact SMTP server and send Message
    host = mail_params.get('host', 'localhost')
    use_ssl = mail_params.get('SSL', False)
    use_tsl = mail_params.get('TLS', False)
    port = mail_params.get('port', 465 if use_ssl else 25)
    smtp = aiosmtplib.SMTP(hostname=host, port=port, use_tls=use_ssl)
    await smtp.connect()
    if use_tsl:
        await smtp.starttls()
    if 'user' in mail_params:
        await smtp.login(mail_params['user'], mail_params['password'])
    await smtp.send_message(msg)
    await smtp.quit()


# 模拟发送邮件，开发时用
async def fake_send_mail_async(sender, to, subject, text, text_type='plain', **params):
    import asyncio
    await asyncio.sleep(0.2)
    print('邮件发送成功.........')
    print(text)
